/*
 * SDF布尔运算说明：
 * 
 * 在SDF中，距离值的含义：
 * - 负值：点在形状内部
 * - 正值：点在形状外部  
 * - 零值：点在形状边界上
 * 
 * SDF布尔运算公式：
 * - 并集 (Union):        min(d1, d2)
 * - 交集 (Intersection): max(d1, d2) 
 * - 差集 (Subtraction):  max(d1, -d2)  // 从d1中减去d2
 * 
 * 重要：必须先进行布尔运算，再应用smoothstep！
 * 如果提前应用smoothstep，会破坏距离场的数学性质。
 * ----> 先进行sdf计算 再计算差集才行 <------
 */

float sdCircle( float r, vec2 uv ) {
    return length(uv) - r;
}

float sdCircleMoved( float r, vec2 uv, vec2 zeroPoint ) {
    return length( distance( uv, zeroPoint ) ) - r;
}

/*
// 绘制圆 并集 交集 差集
void main() {
    vec2 uv = ( gl_FragCoord.xy - 0.5*iResolution.xy )*2.0 / iResolution.yy;
    float r = 0.2;
    
    // 计算两个圆的SDF距离值（不要提前应用smoothstep）
    float d1 = sdCircle( r, uv );                           // 中心圆
    float d2 = sdCircleMoved( r, uv, vec2( 0.2, -0.26 ) );  // 偏移圆
    
    // SDF布尔运算（在原始距离值上进行）
    // float d = min( d1, d2 );     // 并集 (Union)
    // float d = max( d1, d2 );     // 交集 (Intersection) 
    float d = max( d1, -d2 );       // 差集 (Subtraction): 从d1中减去d2
    
    // 最后再应用smoothstep进行抗锯齿
    d = smoothstep( 0.0, 0.01, d );
    
    gl_FragColor = vec4( vec3(d), 1.0 );
}
*/

/*----------------------------------------------------*/

#define PI 3.14159265359
mat2 rotation2d(float angle){
    float s=sin(angle);
    float c=cos(angle);

    return mat2(
        c,-s,
        s,c
    );
}

vec2 rotate(vec2 v,float angle){
    return rotation2d(angle)*v;
}

float sdBox(in vec2 p,in vec2 b)
{
    vec2 d=abs(p)-b;
    return length(max(d,0.))+min(max(d.x,d.y),0.);
}

// 圆角
float opRound(in float d,in float r)
{
    return d-r;
}
// 镂空操作 r 要小 否则没有效果
float opOnion(in float d,in float r)
{
    return abs(d)-r;
}

void main() {
    // [0,1] --(-0.5)-->  [-0.5, 0.5]  --(*2.0)--> [-1, 1]
    vec2 uv = ( gl_FragCoord.xy - 0.5*iResolution.xy )*2.0 / iResolution.xx;
    uv = rotate(uv, 2.0 * PI * sin( iTime*0.2 ));
    float r = 0.1;
    // float d = sdCircle( r, uv );
    float d = sdBox( uv, vec2( 0.1, 0.3 ) );
    d = opOnion( d, 0.02 );
    /* 添加圆 用于裁剪 */
    float d_circle = sdCircle( r, uv );
    
    // 差集 镂空内部减去一个圆
    d = max( d, -d_circle );

    // d = smoothstep( r, r+0.01, d );         // 圆角效果
    d = smoothstep( 0.0, 0.01, d );         // 标准矩形

    // mix 示例 #define mix(x,y,t) x*(1.-t)+y*t
    vec3 color_inner = vec3( 0.3, 0.1, 0.8 );
    // Q: 如何创建 渐变的 inner_color 且随着形状运动?
    vec3 color_inner_1 = vec3( 0.0, 0.0, 0.9 );
    vec3 color_inner_2 = vec3( 0.9, 0.0, 0.0 );
    color_inner = mix( color_inner_1, color_inner_2, (uv.x + 0.5) );

    vec3 color_outer = vec3(1.0);
    // Q: 为什么inner 和 outer 是这样写的? 为什么不反着填?
    vec3 color_final = mix( color_inner, color_outer, d );

    gl_FragColor = vec4( color_final, 1.0 );
}